package myerr

import (
	"database/sql"
	"log"
	"net/http"
)

// ResError response error return
type ResError struct {
	ErrMsg
	StatusCode int                    `json:"code"`
	Data       interface{}            `json:"data,omitempty"`
	MapData    map[string]interface{} `json:"-"`
	hideErr    bool                   `json:"-"`
}

const (
	initCode = -1
	SuccCode = 1
	FailCode = 0
)

// AppendData 追加随带数据
func (e *ResError) AppendData(key string, val interface{}) *ResError {
	if key != "" {
		if e.MapData == nil {
			e.MapData = map[string]interface{}{}
		}
		e.MapData[key] = val
		e.Data = e.MapData
	}
	return e
}

// GetMessage 获取错误信息
func (e *ResError) GetMessage() string {
	if e.Err != nil {
		return e.Err.Error()
	}
	return e.Msg
}

// IsSuccess 是否成功
func (e *ResError) IsSuccess() bool {
	return e.StatusCode == SuccCode
}

// IsFail 是否失败
func (e *ResError) IsFail() bool {
	return e.StatusCode != initCode && e.StatusCode != SuccCode
}

// ClearSuccess 清除成功
func (e *ResError) ClearSuccess() *ResError {
	e.StatusCode = initCode
	return e
}

// SetMessage ..
func (e *ResError) SetMessage(msg string) *ResError {
	e.Msg = msg
	if e.StatusCode == initCode {
		e.StatusCode = FailCode
	}
	return e
}

// SetSuccess 设置成功
func (e *ResError) SetSuccess(msg string) *ResError {
	e.StatusCode = SuccCode
	e.Msg = msg
	return e
}

func (e *ResError) SetErrShow(showErr bool) *ResError {
	e.hideErr = !showErr
	return e
}

// SetError ..
func (e *ResError) SetError(err error) *ResError {
	e.Err = err
	if err == sql.ErrNoRows {
		e.Msg = http.StatusText(http.StatusNotFound)
		e.StatusCode = http.StatusNotFound
	} else if err != nil {
		if e.hideErr {
			e.SetMessage(http.StatusText(http.StatusInternalServerError))
		} else {
			if e.Msg == "" {
				e.SetMessage(err.Error())
			}
		}
		e.StatusCode = http.StatusInternalServerError
	}
	if e.StatusCode == initCode {
		e.StatusCode = FailCode
	}
	return e
}

func (e *ResError) SetErrMsg(em ErrMsg) {
	if em.Ret {
		e.SetSuccess(em.Msg)
	} else if em.Err != nil {
		e.SetError(em.Err)
	} else {
		e.SetMessage(em.Msg)
	}
}

// Print 设置成功
func (e *ResError) Print(ip string) {
	log.Printf("[%s]Quest: StatusCode: %d, Message: %s\n", ip, e.StatusCode, e.Msg)
}

// New 新建对象
func New() *ResError {
	return &ResError{
		StatusCode: initCode,
	}
}
